/*
 * Copyright © 2017 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */

package cn.hermit.nio.http.server;

import cn.hermit.nio.http.Http;
import cn.hermit.util.StringUtils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * @author JackGao 高建国
 * @description //TODO 设计说明
 * @date 29/5/2017
 */
public class HttpResponse implements Http {

    protected String status;

    protected int statusCode;

    protected Map<String, Object> header = new TreeMap<String, Object>();

    protected byte[] headerBytes = null;

    protected byte[] body;

    /**
     * status default to 200
     */
    public HttpResponse() {
        status = OK_200;
        statusCode = 200;
    }

    public HttpResponse addHeader(String key, Object value) {
        header.put(key, value);
        headerBytes = null;
        return this;
    }

    public void clear() {
        status = OK_200;
        header.clear();
    }

    public byte[] getHeaderBytes() {
        if (headerBytes == null) {
            headerBytes = toString().getBytes();
        }
        return headerBytes;
    }

    public void setHeaderBytes(byte[] headerBytes) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(headerBytes)));
            String line;
            while (true) {
                line = reader.readLine();
                if(StringUtils.isBlank(line)) {
                    break;
                }
                if(line.startsWith("HTTP/")) {
                    setStatus(line);
                }else {
                    int idx = line.indexOf(':');
                    if(idx == -1) continue;
                    String name = line.substring(0, idx);
                    String val = line.substring(idx+1);
                    header.put(name, val.trim());
                }
            }
        } catch (IOException e) {
            //ignored
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    //ignored
                }
            }
        }
        this.headerBytes = null;
    }

    public HttpResponse setStatus(String status) {
        this.status = status;
        if (status.contains("200")) {
            statusCode = 200;
        } else if (status.contains("404")) {
            statusCode = 404;
        } else if (status.contains("500")) {
            statusCode = 500;
        }
        return this;
    }

    public byte[] getBody() {
        return body;
    }

    public HttpResponse setBody(byte[] body) {
        this.body = body;
        return this;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(120);
        sb.append(status).append(NEWLINE);
        Set<String> keySet = header.keySet();
        for (String key : keySet) {
            sb.append(key).append(": ").append(header.get(key)).append(NEWLINE);
        }
        sb.append(NEWLINE); // empty line;
        return sb.toString();
    }

}
